package club.xyes.remotedisplay.util;

public class ByteUtil {
    private static final int BYTE_SIZE = 8;

    public static int reverse(int data, int size) {
        int res = 0;
        for (int i = 0; i < size; i++) {
            if ((data & 0x80) == 0) {
                res |= 0;
            } else {
                res |= 0x80;
            }
            if (i != BYTE_SIZE - 1) {
                res >>= 1;
                data <<= 1;
            }
        }
        return res;
    }

    public static int reverse(int data) {
        return reverse(data, BYTE_SIZE);
    }

    public static int[] reverse(int[] data, int size) {
        for (int i = 0; i < data.length; i++) {
            data[i] = reverse(data[i], size);
        }
        return data;
    }

    public static int[][] reverse(int[][] data, int size) {
        for (int i = 0; i < data.length; i++) {
            data[i] = reverse(data[i], size);
        }
        return data;
    }

    public static void reverse(int[][] data) {
        reverse(data, BYTE_SIZE);
    }

    /**
     * 字节前景背景覆盖
     *
     * @param background 背景
     * @param foreground 前景
     * @param offset     偏移 >0:向右偏移  <0向左偏移
     * @return 覆盖结果
     */
    public static int superposition(int background, int foreground, int offset) {
        //偏移字节
        if (offset > 0) {
            foreground >>= offset;
        } else if (offset < 0) {
            foreground <<= -offset;
        }
        return background | foreground;
    }

    /**
     * 字节前景背景覆盖
     *
     * @param background 背景
     * @param foreground 前景
     * @param offset     偏移
     * @param start      开始坐标
     * @return 覆盖结果
     */
    public static int[] superposition(int[] background, int[] foreground, int start, int offset) {
        assert background.length - start == foreground.length : "前景大小和背景大小不一致";
        for (int i = 0; i < foreground.length; i++) {
            background[start + i] = superposition(background[start + i], foreground[i], offset);
        }
        return background;
    }

    public static int leftShiftWith1(int s, int offset) {
        for (int i = 0; i < offset; i++) {
            s <<= 1;
            s += 1;
        }
        return s;
    }

    public static int rightShiftWith1(int s, int offset) {
        for (int i = 0; i < offset; i++) {
            s >>= 1;
            s |= 0x80;
        }
        return s;
    }

}
